package com.neuronbit.businessflow.flow;

import com.neuronbit.businessflow.flow.parser.FlowNode;
import com.neuronbit.businessflow.flow.parser.ModelParser;
import com.neuronbit.businessflow.flow.project.Project;
import com.neuronbit.businessflow.flow.source.BpmJavaSource;
import com.neuronbit.javaparser.ast.CompilationUnit;
import lombok.Getter;
import org.apache.commons.io.FileUtils;

import javax.xml.stream.XMLStreamException;
import java.io.File;
import java.io.IOException;

/**
 * The type Bpm file.
 */
public class BpmFile {
    private final File bpmFile;
    @Getter
    private final Project project;
    private final File javaFile;
    @Getter
    private final FlowNode flow;
    @Getter
    private final String packageName;

    /**
     * Instantiates a new Bpm file.
     *
     * @param bpmFile the bpm file
     * @param project the project
     * @throws IOException        the io exception
     * @throws XMLStreamException the xml stream exception
     */
    public BpmFile(File bpmFile, Project project) throws IOException, XMLStreamException {
        this.bpmFile = bpmFile;
        this.javaFile = new File(bpmFile.getAbsolutePath().replace(".bpm", ".java"));
        this.project = project;
        this.flow = new ModelParser(project).parse(FileUtils.readFileToString(bpmFile, "utf-8"));

        CompilationUnit compilationUnit = project.parseJava(javaFile);
        flow.setCompilationUnit(compilationUnit);
        if (compilationUnit.getPackageDeclaration().isPresent()) {
            this.packageName = compilationUnit.getPackageDeclaration().get().getName().asString();
        } else {
            this.packageName = "";
        }
    }

    /**
     * Generate java code.
     */
    public void generateJavaCode() {
        try {
            new BpmJavaSource(this).generate();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String toString() {
        return bpmFile.getAbsolutePath();
    }
}
